package com.ares.basic.utils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.regex.Pattern;

/**
 * @author tcg
 */
public class NumberUtil {

    private static final String DEFUALT_FORMAT_PATTERN = "#.##";

    private static final String SHORT_FORMAT_PATTERN = "#.#";

    private static final String DOUBLE_TO_INTEGER_FORMAT_PATTERN = "#";

    private static final String THREE_FORMAT_PATTERN = "#.###";

    private static String[] units = {"", "十", "十", "十", "十"};
    //            { "", "十", "百", "千", "万", "十万", "百万", "千万", "亿",
    //            "十亿", "百亿", "千亿", "万亿" };
    private static char[] numArray = {};
    //            { '零', '一', '二', '三', '四', '五', '六', '七', '八', '九' };
    private static char[] weekArray = {};
    //            { '一', '二', '三', '四', '五', '六', '日' };

    public static String toSingleCnNum(int num) {
        return new StringBuilder().append(numArray[num]).toString();
    }

    public static String toSingleCnWeekNum(int num) {
        return new StringBuilder().append(weekArray[num]).toString();
    }

    public static String setScale(Double num) {
        return setScale(num, null);
    }

    public static String setScale(Double num, Integer scale) {
        if (num == null) {
            return null;
        }
        if (scale == null) {
            scale = 2;
        }
        BigDecimal b = new BigDecimal(num);
        return b.setScale(scale, BigDecimal.ROUND_HALF_UP) + "";
    }

    public static Float setScale(Float num, Integer scale) {
        if (num == null) {
            return null;
        }
        if (scale == null) {
            scale = 2;
        }
        BigDecimal b = new BigDecimal(num);
        return b.setScale(scale, BigDecimal.ROUND_HALF_UP).floatValue();
    }

    public static Double formatDouble(Double num, Integer scale) {
        if (num == null) {
            return 0.0D;
        }
        if (scale == null) {
            scale = 2;
        }
        BigDecimal b = new BigDecimal(num);
        return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public static Float formatFloat(Float num) {
        if (num == null) {
            return null;
        }
        DecimalFormat f = new DecimalFormat();
        f.applyPattern(DEFUALT_FORMAT_PATTERN);
        return formatStringToFloat(f.format(num));
    }

    public static Float formatFloat(Float num, String pattern) {
        if (num == null) {
            return null;
        }
        DecimalFormat f = new DecimalFormat();
        f.applyPattern(pattern);
        return formatStringToFloat(f.format(num));
    }

    public static String formatFloatToString(Float num) {
        if (num == null) {
            return null;
        }
        DecimalFormat f = new DecimalFormat();
        f.applyPattern(DEFUALT_FORMAT_PATTERN);
        return f.format(num);
    }

    public static String formatFloatToString(Float num, String pattern) {
        if (num == null || pattern == null) {
            return null;
        }
        DecimalFormat f = new DecimalFormat();
        f.applyPattern(pattern);
        return f.format(num);
    }

    public static Float formatStringToFloat(String str) {
        if (str == null) {
            return null;
        }
        return Float.parseFloat(str.trim());
    }

    /**
     * 判断一个字符串是否是正整数
     */
    public static boolean isPositiveInteger(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }

    /**
     * 是否是一个正浮点数
     */
    public static boolean isPositiveFloat(String str) {
        return str.matches("\\d+\\.?\\d*");
    }

    /**
     * 将double四舍五入转换为int
     */
    public static Integer formatDoubleToInteger(double num) {
        DecimalFormat f = new DecimalFormat();
        f.applyPattern(DOUBLE_TO_INTEGER_FORMAT_PATTERN);
        return Integer.parseInt(f.format(num));
    }

    /**
     * 2个int相除 四舍五入 保留N位小数
     *
     * @param i     整数1
     * @param j     整数2
     * @param scale 保留的小数位数
     * @return float
     */
    public static float divideGetFloat(int i, int j, int scale) {
        BigDecimal x = new BigDecimal(i);
        BigDecimal y = new BigDecimal(j);
        return x.divide(y, scale, BigDecimal.ROUND_HALF_UP).floatValue();
    }

    public static int divideGetInteger(int i, int j) {
        BigDecimal x = new BigDecimal(i);
        BigDecimal y = new BigDecimal(j);
        return x.divide(y, 0, BigDecimal.ROUND_HALF_UP).intValue();
    }

    public static float divideGetFloat(float i, int j, int scale) {
        BigDecimal x = new BigDecimal(i);
        BigDecimal y = new BigDecimal(j);
        return x.divide(y, scale, BigDecimal.ROUND_HALF_UP).floatValue();
    }

    public static float divideGetFloat(double i, int j, int scale) {
        BigDecimal x = new BigDecimal(i);
        BigDecimal y = new BigDecimal(j);
        return x.divide(y, scale, BigDecimal.ROUND_HALF_UP).floatValue();
    }

    /**
     * 获得百分比
     */
    public static float getPercent(double i) {
        BigDecimal d = new BigDecimal(i);
        BigDecimal l = new BigDecimal(100);
        return d.multiply(l).floatValue();
    }

    public static String getPercent(Integer num1, Integer num2, Integer scale) {
        return getPercent(new Double(num1), new Double(num2), scale);
    }

    public static String getIntegerPercent(Integer num1, Integer num2, Integer scale) {
        return getIntegerPercent(new Double(num1), new Double(num2), scale);
    }

    public static String getPercent(Double num1, Double num2, int scale) {
        if (num2 == 0 || num2 == null) {
            return "100";
        }

        if (num1 == null) {
            return "0";
        }

        NumberFormat numberFormat = NumberFormat.getInstance();
        numberFormat.setMaximumFractionDigits(scale);
        return numberFormat.format(num1 / num2 * 100);
    }

    public static String getIntegerPercent(Double num1, Double num2, int scale) {
        if (num2 == 0 || num2 == null) {
            return "100%";
        }

        if (num1 == null) {
            return "0%";
        }

        NumberFormat numberFormat = NumberFormat.getInstance();
        numberFormat.setMaximumFractionDigits(scale);
        return numberFormat.format(num1 / num2 * 100);
    }

    /**
     * 2个double相除 四舍五入 保留N位小数
     *
     * @param scale 需要保留的位数
     * @return double
     */
    public static double divide(double i, double j, int scale) {
        BigDecimal x = new BigDecimal(i);
        BigDecimal y = new BigDecimal(j);
        return x.divide(y, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 2个double相除  保留N位小数
     *
     * @param scale 需要保留的位数
     * @return double
     */
    public static Double divideDouble(double i, double j, int scale) {
        BigDecimal x = new BigDecimal(i);
        BigDecimal y = new BigDecimal(j);
        return x.divide(y, scale, BigDecimal.ROUND_DOWN).doubleValue();
    }

    /**
     * 2个double相乘 四舍五入 保留N位小数
     *
     * @param scale 需要保留的位数
     * @return double
     */
    public static Double multiply(double i, double j, int scale) {
        BigDecimal x = new BigDecimal(i);
        BigDecimal y = new BigDecimal(j);
        return x.multiply(y).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public static double add(double i, double j, int scale) {
        BigDecimal x = new BigDecimal(i);
        BigDecimal y = new BigDecimal(j);
        return x.add(y).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * double除int 四舍五入 保留N位小数
     *
     * @param scale 需要保留的位数
     * @return double
     */
    public static double divideGetDouble(double i, int j, int scale) {
        BigDecimal x = new BigDecimal(i);
        BigDecimal y = new BigDecimal(j);
        return x.divide(y, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * double乘int  保留N位小数
     *
     * @param scale 需要保留的位数
     * @return double
     */
    public static double multiplyGetDouble(double i, int j, int scale) {
        BigDecimal x = new BigDecimal(i);
        BigDecimal y = new BigDecimal(j);
        return x.multiply(y).setScale(scale, BigDecimal.ROUND_DOWN).doubleValue();
    }
    /*	*/

    /**
     * 2个double相乘 遇大于0的小数始终进位 保留N位小数
     */
    //	public static Double multiplyInRoundUp(double i, double j, int scale) {
    //		BigDecimal x = new BigDecimal(i);
    //		BigDecimal y = new BigDecimal(j);
    //		return x.multiply(y).setScale(scale, BigDecimal.ROUND_UP).doubleValue();
    //	}
    public static int getMultiplyInt(double i, double j) {
        return multiply(i, j, 2).intValue();
    }

    public static double subtract(double i, double j, int scale) {
        return new BigDecimal(i).subtract(new BigDecimal(j)).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public static String formatPrice(Double price) {
        if (price == null) {
            return "0.00";
        }
        return new BigDecimal(price).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    }

    public static String formatIntPrice(Double price) {
        if (price == null) {
            return "0";
        }
        return new BigDecimal(price).setScale(0, BigDecimal.ROUND_HALF_UP).toString();
    }

    public static String formatPrice2(Double price) {
        if (price == null) {
            return null;
        }
        return new BigDecimal(price).setScale(0, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 小于10前面补0
     */
    public static String numberStr(Integer num) {
        if (num < 10) {
            return String.format("%02d", num);
        }
        return String.valueOf(num);
    }

    /**
     * 小数点为0时转换整数
     */
    public static String doubleTrans(Double num) {
        if (num % 1.0 == 0) {
            return String.valueOf(num.longValue());
        }
        return String.valueOf(num);
    }

    /**
     * Double 类型数据保留两位小数（四舍五入）(整数时补两位小数)
     */
    public static String doubleConversion(Double num) {
        DecimalFormat df = new DecimalFormat("#.00");
        return df.format(num);
    }

    public static Double sum(List<Double> values) {
        if (values == null || values.isEmpty()) {
            return 0d;
        }

        return values.stream().filter(Objects::nonNull).reduce(0d, (p1, p2) -> NumberUtil.add(p1, p2, 2));
    }

    public static String leftPad(int length, String sample, char pad) {
        if (sample.length() >= length) {
            return sample;
        }

        length = length - sample.length();
        String padStr = pad + "";
        StringBuilder sb = new StringBuilder();

        while (length > 0) {
            if (length % 2 != 0) {
                sb.append(padStr);
            }

            padStr += padStr;
            length = length >> 1;
        }

        sb.append(sample);
        return sb.toString();
    }

    /**
     * 生成随机6位手机验证码,开发时调用
     *
     * @return
     */
    public static String randomVerityCode() {
        int[] array = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        Random rand = new Random();
        for (int i = 10; i > 1; i--) {
            int index = rand.nextInt(i);
            int tmp = array[index];
            array[index] = array[i - 1];
            array[i - 1] = tmp;
        }
        if (array[0] == 0) {
            array[0] = 5;
        }
        int result = 0;
        for (int i = 0; i < 6; i++) {
            result = result * 10 + array[i];
        }
        return "" + result;
    }
}
